/*
*
==============================================================================
*  Name        : 
*  Part of     : Omen Game Engine - DirectX 10 Plugin
*  Description : 
*  Version     : 1.0
*
*  Copyright (c) 2013 Lauri Kortevaara.
* 
==============================================================================
*/

#define DIRECTX_10_PLUGIN_SOURCE 1

/// DirectX_10_Plugin Headers
#include "DirectX_10_Plugin.h"

#include "DirectX_10_Renderer.h"
#include "DirectX_10_GraphicsDriver.h"
#include "DirectX_10_ColorShader.h"
#include "DirectX_10_LightShader.h"
#include "DirectX_10_Light.h"
#include "DirectX_10_BasicShader.h"
#include "DirectX_10_Texture.h"

/// STL Headers
#include <iostream>
#include <sstream>

using namespace Omen;


DirectX_10_Renderer::DirectX_10_Renderer()
{
    m_device = 0;
    m_pSwapChain = 0;
    m_renderTargetView = 0;
    m_depthStencilBuffer = 0;
    m_depthStencilState = 0;
    m_depthStencilView = 0;
    m_rasterState = 0;
    rasterizer_wireframe = 0;
    m_frameIndex = 0;

    m_pListMeshes = NULL;
    m_maxNumMeshes = 0;

    m_screenNear = 0.1;
    m_screenFar = 1000.0;

    m_bVSyncEnabled = true;
    m_bBoundingVolumesVisible = false;
    m_bOctreeVisible = false;
}

void DirectX_10_Renderer::initializeMatrices()
{
    // Setup the projection matrix.
    m_fieldOfView = (float)D3DX_PI / 4.0f;
    m_screenAspect = (float)m_window.width() / (float)m_window.height();

    // Create the projection matrix for 3D rendering.
    D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, (float)m_fieldOfView, (float)m_screenAspect, (float)m_screenNear, (float)m_screenFar);

    // Initialize the world matrix to the identity matrix.
    D3DXMatrixIdentity(&m_worldMatrix);

    // Create an orthographic projection matrix for 2D rendering.
    D3DXMatrixOrthoLH(&m_orthoMatrix, (float)m_window.width(), (float)m_window.height(), (float)m_screenNear, (float)m_screenFar);
}

void DirectX_10_Renderer::initializeRenderer()
{
    D3D10_RASTERIZER_DESC rasterizerState;
    rasterizerState.AntialiasedLineEnable = false;
    rasterizerState.CullMode = D3D10_CULL_BACK;
    rasterizerState.DepthBias = 0;
    rasterizerState.DepthBiasClamp = 0.0f;
    rasterizerState.DepthClipEnable = true;
    rasterizerState.FillMode = D3D10_FILL_SOLID;
    rasterizerState.FrontCounterClockwise = true;
    rasterizerState.MultisampleEnable = false;
    rasterizerState.ScissorEnable = false;
    rasterizerState.SlopeScaledDepthBias = 0.0f;
 
    m_device->CreateRasterizerState( &rasterizerState, &this->m_rasterState);
    m_device->RSSetState(m_rasterState);

    ::D3DX10CreateSprite( m_device, 1, &m_textSprite );
    ::D3DX10CreateFont( m_device, 12, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Lucida Console"), &m_font );
}

unsigned long DirectX_10_Renderer::windowHandle() const 
{
    return m_window.windowHandle();
}

void DirectX_10_Renderer::beginRendering() const
{
    // Clear the buffers to begin the scene.
    float color[4];
    
    // Setup the color to clear the buffer to.
    color[0] = 0.4f; // red
    color[1] = 0.4f; // green
    color[2] = 0.4f; // blue
    color[3] = 1.0f; // alpha

    // Clear the back buffer.
    m_device->ClearRenderTargetView(m_renderTargetView, color);
    
    // Clear the depth buffer.
    m_device->ClearDepthStencilView(m_depthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0);
    m_device->OMSetDepthStencilState(m_depthStencilState, 1);
}

void DirectX_10_Renderer::endRendering() const
{
    // Present the back buffer to the screen since rendering is complete.
    if(m_bVSyncEnabled)
    {
        // Lock to screen refresh rate.
        m_pSwapChain->Present(0, 0);
    }
    else
    {
        // Present as fast as possible.
        m_pSwapChain->Present(0, 0);
    }
}

void DirectX_10_Renderer::render(Omen::ICamera* pCamera) const
{
    m_pCamera = pCamera;
}

void DirectX_10_Renderer::render(Omen::ILight** pLights, unsigned int numLights) const
{
}

void DirectX_10_Renderer::addOctreeBuffer( Omen::IOctreeNode* pNode )
{
    OctreeBuffer octreebuf;
    // Create vertex buffer
    AABB aabb = pNode->boundingBox();

    octreebuf.m_octreeVerties = 8;
    octreebuf.m_octreeVerties = NULL;
    octreebuf.m_pOctreeIndices = NULL;
    octreebuf.m_octreeIndices = 0;

    DX_10_VertexType* vertices;
    D3D10_BUFFER_DESC vertexBufferDesc;
    D3D10_SUBRESOURCE_DATA vertexData;
    HRESULT result;
    unsigned int numVertices = 8;

    Omen::Vector3d* pVertices = new Omen::Vector3d[numVertices];
    
    Omen::Vector3d min = pNode->boundingBox().minimum();
    Omen::Vector3d max = pNode->boundingBox().maximum();
        
    Omen::Vector3d center = (max+min) / 2.0f;
    Omen::Vector3d extent = (max-min) / 2.0f;

    // Create the child nodes
    Omen::Vector3d frontBottomLeft  = center-Vector3d(extent.x, extent.y, extent.z);
    Omen::Vector3d frontTopLeft     = center-Vector3d(extent.x, 0.0     , extent.z)+Vector3d(0.0,extent.y,0.0);
    Omen::Vector3d frontTopRight    = center-Vector3d(0.0     , 0.0     , extent.z)+Vector3d(extent.x,extent.y,0.0);
    Omen::Vector3d frontBottomRight = center-Vector3d(0.0     , extent.y, extent.z)+Vector3d(extent.x,0.0,0.0);
    Omen::Vector3d backBottomLeft   = center-Vector3d(extent.x, extent.y, 0.0)     +Vector3d(0.0,0.0,extent.z);
    Omen::Vector3d backTopLeft      = center-Vector3d(extent.x, 0.0     , 0.0)     +Vector3d(0.0,extent.y,extent.z);
    Omen::Vector3d backTopRight     = center                                       +Vector3d(extent.x,extent.y,extent.z);
    Omen::Vector3d backBottomRight  = center-Vector3d(0.0     , extent.y, 0.0)     +Vector3d(extent.x,0.0,extent.z);
    
    pVertices[0] = frontBottomLeft;pVertices[1] = frontTopLeft;pVertices[2] = frontTopRight; pVertices[3] = frontBottomRight;
    pVertices[4] = backBottomLeft; pVertices[5] = backTopLeft; pVertices[6] = backTopRight;  pVertices[7] = backBottomRight;

    // Create the vertex array.
    vertices = new DX_10_VertexType[numVertices];
    if(!vertices)
    {
        return;
    }

    // Load the vertex array and index array with data.
    for( unsigned long i=0; i<numVertices; i++)
    {
        vertices[i].position = D3DXVECTOR4(pVertices[i].x, pVertices[i].y, pVertices[i].z, 1.0);
        vertices[i].normal =   D3DXVECTOR4(0.0,0.0,0.0, 1.0);
        vertices[i].texture =  D3DXVECTOR2(0.0,0.0);
    }

    // Set up the description of the vertex buffer.
    vertexBufferDesc.Usage      = D3D10_USAGE_DEFAULT;
    vertexBufferDesc.ByteWidth  = sizeof(DX_10_VertexType) * numVertices;
    vertexBufferDesc.BindFlags  = D3D10_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = 0;
    vertexBufferDesc.MiscFlags  = 0;

    // Give the subresource structure a pointer to the vertex data.
    vertexData.pSysMem = vertices;

    // Now finally create the vertex buffer.
    ID3D10Buffer* pVertexBuffer = NULL;
    result = this->m_device->CreateBuffer(&vertexBufferDesc, &vertexData, &pVertexBuffer);
    if(FAILED(result))
    {
        return;
    }

    // Release the arrays now that the vertex and index buffers have been created and loaded.
    delete [] vertices;
    vertices = 0;

    // Set the vertex buffer pointer to the mesh so that it can be rendered using that
    octreebuf.m_pOctreeVertices = pVertexBuffer;

    // Create index buffer
    unsigned long* indices;
    D3D10_BUFFER_DESC indexBufferDesc;
    D3D10_SUBRESOURCE_DATA indexData;
    
    unsigned int indexCount = 24;
    
    // Create the index array.
    indices = new unsigned long[indexCount];
    if(!indices)
    {
        return;
    }

    /*
    
    1  2      5  6

    0  3      4  7

    */

    // Load the index array with data.
    indices[0] = 0; indices[1] = 1;
    indices[2] = 1; indices[3] = 2;
    indices[4] = 2; indices[5] = 3;
    indices[6] = 3; indices[7] = 0;
    indices[8] = 4; indices[9] = 5;
    indices[10] = 5; indices[11] = 6;
    indices[12] = 6; indices[13] = 7;
    indices[14] = 7; indices[15] = 4;
    indices[16] = 0; indices[17] = 4;
    indices[18] = 1; indices[19] = 5;
    indices[20] = 2; indices[21] = 6;
    indices[22] = 3; indices[23] = 7;
    

    // Set up the description of the index buffer.
    indexBufferDesc.Usage           = D3D10_USAGE_DEFAULT;
    indexBufferDesc.ByteWidth       = sizeof(unsigned long) * indexCount;
    indexBufferDesc.BindFlags       = D3D10_BIND_INDEX_BUFFER;
    indexBufferDesc.CPUAccessFlags  = 0;
    indexBufferDesc.MiscFlags       = 0;

    // Give the subresource structure a pointer to the index data.
    indexData.pSysMem = indices;

    // Create the index buffer.
    ID3D10Buffer* pIndexBuffer = NULL;
    result = m_device->CreateBuffer(&indexBufferDesc, &indexData, &pIndexBuffer);
    if(FAILED(result))
    {
        return;
    }

    octreebuf.m_pOctreeIndices = pIndexBuffer;
    octreebuf.m_octreeIndices = 24;
    octreebuf.m_depth = pNode->depth();

    // Release the arrays now that the vertex and index buffers have been created and loaded.
    delete [] indices;
    indices = 0;

    m_listOctreeBuffers.push_back( octreebuf );
    Omen::IOctreeNode** pChildren = pNode->children();
    for( unsigned int i=0; i < 8; ++i )
    {
        if( pChildren[i] )
            addOctreeBuffer(pChildren[i]);
    }
}

void DirectX_10_Renderer::createOctreeBuffers( IScene* pScene )
{
    if( !pScene )
        return;
    IOctree* pOctree = pScene->octree();
    if( !pOctree )
        return;

    IOctreeNode* pOctreeNode = pOctree->rootNode();
    if( !pOctreeNode )
        return;

    if( !rasterizer_wireframe )
    {
        // Create wireframe rasterizer state
        D3D10_RASTERIZER_DESC wfd;
        ZeroMemory(&wfd, sizeof(D3D10_RASTERIZER_DESC));
        wfd.FillMode = D3D10_FILL_WIREFRAME;
        wfd.CullMode = D3D10_CULL_BACK;
        wfd.MultisampleEnable = true;
        wfd.AntialiasedLineEnable = true;

        m_device->CreateRasterizerState(&wfd, &rasterizer_wireframe);
    }
    m_device->RSSetState(rasterizer_wireframe);
    addOctreeBuffer(pOctreeNode);
}

void DirectX_10_Renderer::addBoundingBoxBuffer( const Omen::AABB& box )
{
    BoundingBoxBuffer buffer;
    // Create vertex buffer

    buffer.m_numVertices = 8;
    buffer.m_pVertices = NULL;
    buffer.m_numIndices = 0;
    buffer.m_pIndices = NULL;

    DX_10_VertexType* vertices;
    D3D10_BUFFER_DESC vertexBufferDesc;
    D3D10_SUBRESOURCE_DATA vertexData;
    HRESULT result;
    unsigned int numVertices = 8;

    Omen::Vector3d* pVertices = new Omen::Vector3d[numVertices];
    
    Omen::Vector3d min = box.minimum();
    Omen::Vector3d max = box.maximum();
        
    Omen::Vector3d center = (max+min) / 2.0f;
    Omen::Vector3d extent = (max-min) / 2.0f;

    // Create the child nodes
    Omen::Vector3d frontBottomLeft  = center-Vector3d(extent.x, extent.y, extent.z);
    Omen::Vector3d frontTopLeft     = center-Vector3d(extent.x, 0.0     , extent.z)+Vector3d(0.0,extent.y,0.0);
    Omen::Vector3d frontTopRight    = center-Vector3d(0.0     , 0.0     , extent.z)+Vector3d(extent.x,extent.y,0.0);
    Omen::Vector3d frontBottomRight = center-Vector3d(0.0     , extent.y, extent.z)+Vector3d(extent.x,0.0,0.0);
    Omen::Vector3d backBottomLeft   = center-Vector3d(extent.x, extent.y, 0.0)     +Vector3d(0.0,0.0,extent.z);
    Omen::Vector3d backTopLeft      = center-Vector3d(extent.x, 0.0     , 0.0)     +Vector3d(0.0,extent.y,extent.z);
    Omen::Vector3d backTopRight     = center                                       +Vector3d(extent.x,extent.y,extent.z);
    Omen::Vector3d backBottomRight  = center-Vector3d(0.0     , extent.y, 0.0)     +Vector3d(extent.x,0.0,extent.z);
    
    pVertices[0] = frontBottomLeft;pVertices[1] = frontTopLeft;pVertices[2] = frontTopRight; pVertices[3] = frontBottomRight;
    pVertices[4] = backBottomLeft; pVertices[5] = backTopLeft; pVertices[6] = backTopRight;  pVertices[7] = backBottomRight;

    // Create the vertex array.
    vertices = new DX_10_VertexType[numVertices];
    if(!vertices)
    {
        return;
    }

    // Load the vertex array and index array with data.
    for( unsigned long i=0; i<numVertices; i++)
    {
        vertices[i].position = D3DXVECTOR4(pVertices[i].x, pVertices[i].y, pVertices[i].z, 1.0);
        vertices[i].normal =   D3DXVECTOR4(0.0,0.0,0.0, 1.0);
        vertices[i].texture =  D3DXVECTOR2(0.0,0.0);
    }

    // Set up the description of the vertex buffer.
    vertexBufferDesc.Usage      = D3D10_USAGE_DEFAULT;
    vertexBufferDesc.ByteWidth  = sizeof(DX_10_VertexType) * numVertices;
    vertexBufferDesc.BindFlags  = D3D10_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = 0;
    vertexBufferDesc.MiscFlags  = 0;

    // Give the subresource structure a pointer to the vertex data.
    vertexData.pSysMem = vertices;

    // Now finally create the vertex buffer.
    ID3D10Buffer* pVertexBuffer = NULL;
    result = this->m_device->CreateBuffer(&vertexBufferDesc, &vertexData, &pVertexBuffer);
    if(FAILED(result))
    {
        return;
    }

    // Release the arrays now that the vertex and index buffers have been created and loaded.
    delete [] vertices;
    vertices = 0;

    // Set the vertex buffer pointer to the mesh so that it can be rendered using that
    buffer.m_pVertices = pVertexBuffer;

    // Create index buffer
    unsigned long* indices;
    D3D10_BUFFER_DESC indexBufferDesc;
    D3D10_SUBRESOURCE_DATA indexData;
    
    unsigned int indexCount = 24;
    
    // Create the index array.
    indices = new unsigned long[indexCount];
    if(!indices)
    {
        return;
    }

    /*
    
    1  2      5  6

    0  3      4  7

    */

    // Load the index array with data.
    indices[0] = 0; indices[1] = 1;
    indices[2] = 1; indices[3] = 2;
    indices[4] = 2; indices[5] = 3;
    indices[6] = 3; indices[7] = 0;
    indices[8] = 4; indices[9] = 5;
    indices[10] = 5; indices[11] = 6;
    indices[12] = 6; indices[13] = 7;
    indices[14] = 7; indices[15] = 4;
    indices[16] = 0; indices[17] = 4;
    indices[18] = 1; indices[19] = 5;
    indices[20] = 2; indices[21] = 6;
    indices[22] = 3; indices[23] = 7;
    

    // Set up the description of the index buffer.
    indexBufferDesc.Usage           = D3D10_USAGE_DEFAULT;
    indexBufferDesc.ByteWidth       = sizeof(unsigned long) * indexCount;
    indexBufferDesc.BindFlags       = D3D10_BIND_INDEX_BUFFER;
    indexBufferDesc.CPUAccessFlags  = 0;
    indexBufferDesc.MiscFlags       = 0;

    // Give the subresource structure a pointer to the index data.
    indexData.pSysMem = indices;

    // Create the index buffer.
    ID3D10Buffer* pIndexBuffer = NULL;
    result = m_device->CreateBuffer(&indexBufferDesc, &indexData, &pIndexBuffer);
    if(FAILED(result))
    {
        return;
    }

    buffer.m_pIndices = pIndexBuffer;
    buffer.m_numIndices = 24;

    // Release the arrays now that the vertex and index buffers have been created and loaded.
    delete [] indices;
    indices = 0;

    m_listBoundingBoxBuffers.push_back( buffer );
}

void DirectX_10_Renderer::createBoundingBoxBuffers( IScene* pScene )
{
    if( !pScene )
        return;

    if( !rasterizer_wireframe )
    {
        // Create wireframe rasterizer state
        D3D10_RASTERIZER_DESC wfd;
        ZeroMemory(&wfd, sizeof(D3D10_RASTERIZER_DESC));
        wfd.FillMode = D3D10_FILL_WIREFRAME;
        wfd.CullMode = D3D10_CULL_NONE;
        wfd.MultisampleEnable = true;
        wfd.AntialiasedLineEnable = true;

        m_device->CreateRasterizerState(&wfd, &rasterizer_wireframe);
    }

    for( auto iter = m_listBoundingBoxBuffers.begin(); iter != m_listBoundingBoxBuffers.end(); ++iter )
    {
        iter->m_pVertices->Release();
        iter->m_pIndices->Release();
    }
    m_listBoundingBoxBuffers.clear();

    m_device->RSSetState(rasterizer_wireframe);
    Omen::IModel** models = new Omen::IModel*[pScene->modelCount()];
    pScene->getModels(models,pScene->modelCount());
    for( unsigned long iModel = 0; iModel < pScene->modelCount(); ++iModel )
    {
        Omen::IModel* pModel = models[iModel];
        if( pModel )
        {
            pModel->updateBoundingVolume();
            const Omen::AABB& box = pModel->boundingBox();
            addBoundingBoxBuffer(box);
        }
    }
    delete[] models;
}

/// <summary>Renderer creates a vertex buffer for this mesh</summary>
void DirectX_10_Renderer::createVertexBuffer( IMesh* pMesh ) const
{
    if( pMesh && !pMesh->vertexBufferPtr() && pMesh->vertexCount() )
    {
        Omen::IMesh::Vertex* pVertices;
        unsigned long numVertices = pMesh->vertexCount();
        pVertices = new Omen::IMesh::Vertex[numVertices];
        pMesh->getVertices( pVertices, numVertices );

        DX_10_VertexType* vertices;
        D3D10_BUFFER_DESC vertexBufferDesc;
        D3D10_SUBRESOURCE_DATA vertexData;
        HRESULT result;
    
        // Create the vertex array.
        vertices = new DX_10_VertexType[numVertices];
        if(!vertices)
        {
            return;
        }

        Omen::Float scaleX,scaleY,scaleZ;
        pMesh->scale(scaleX,scaleY,scaleZ);

        // Load the vertex array and index array with data.
        for( unsigned long i=0; i<numVertices; i++)
        {
            vertices[i].position = D3DXVECTOR4(pVertices[i].x*scaleX, pVertices[i].y*scaleY, pVertices[i].z*scaleZ, 1.0);
            vertices[i].normal =   D3DXVECTOR4(pVertices[i].nx, pVertices[i].ny, pVertices[i].nz, 1.0);
            vertices[i].texture =  D3DXVECTOR2(pVertices[i].tu, -pVertices[i].tv);
            //std::cout << "Renderer VertexBuffer vertex#" << i << ", [" << vertices[i].position.x << "," << vertices[i].position.y << "," << vertices[i].position.z << "]" << std::endl;
        }

        // Set up the description of the vertex buffer.
        vertexBufferDesc.Usage      = D3D10_USAGE_DEFAULT;
        vertexBufferDesc.ByteWidth  = sizeof(DX_10_VertexType) * numVertices;
        vertexBufferDesc.BindFlags  = D3D10_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = 0;
        vertexBufferDesc.MiscFlags  = 0;

        // Give the subresource structure a pointer to the vertex data.
        vertexData.pSysMem = vertices;

        // Now finally create the vertex buffer.
        ID3D10Buffer* pVertexBuffer = NULL;
        result = this->m_device->CreateBuffer(&vertexBufferDesc, &vertexData, &pVertexBuffer);
        if(FAILED(result))
        {
            return;
        }

        // Release the arrays now that the vertex and index buffers have been created and loaded.
        delete [] vertices;
        vertices = 0;

        // Set the vertex buffer pointer to the mesh so that it can be rendered using that
        pMesh->setVertexBufferPtr( pVertexBuffer );
    }
}

/// <summary>Renderer creates an index buffer for this mesh</summary>
void DirectX_10_Renderer::createIndexBuffer( IMesh* pMesh ) const
{
    if( pMesh && !pMesh->indexBufferPtr() && pMesh->faceCount()  )
    {
        Omen::IMesh::Face** pFaces;
        unsigned long indexCount = pMesh->faceCount();
        pFaces = new Omen::IMesh::Face*[indexCount];
        pMesh->getFaces( pFaces, indexCount );

        unsigned long* indices;
        D3D10_BUFFER_DESC indexBufferDesc;
        D3D10_SUBRESOURCE_DATA indexData;
        HRESULT result;
        unsigned long i;
    
        // Create the index array.
        indices = new unsigned long[indexCount*3];
        if(!indices)
        {
            return;
        }

        // Load the index array with data.
        for( i=0; i<indexCount; i++)
        {
            indices[i*3] = pFaces[i]->p1;
            indices[i*3+1] = pFaces[i]->p2;
            indices[i*3+2] = pFaces[i]->p3;
        }

        // Set up the description of the index buffer.
        indexBufferDesc.Usage           = D3D10_USAGE_DEFAULT;
        indexBufferDesc.ByteWidth       = sizeof(unsigned long) * indexCount * 3;
        indexBufferDesc.BindFlags       = D3D10_BIND_INDEX_BUFFER;
        indexBufferDesc.CPUAccessFlags  = 0;
        indexBufferDesc.MiscFlags       = 0;

        // Give the subresource structure a pointer to the index data.
        indexData.pSysMem = indices;

        // Create the index buffer.
        ID3D10Buffer* pIndexBuffer = NULL;
        result = m_device->CreateBuffer(&indexBufferDesc, &indexData, &pIndexBuffer);
        if(FAILED(result))
        {
            return;
        }

        // Release the arrays now that the vertex and index buffers have been created and loaded.
        delete [] indices;
        indices = 0;

        pMesh->setIndexBufferPtr(pIndexBuffer);
    }
}

void DirectX_10_Renderer::refreshRenderer( Omen::IModel** pModels, unsigned int numModels )
{
    unsigned long numMeshes = 0;
    static unsigned long maxNumModels = 0;

    createBoundingBoxBuffers(pModels[0]->scene());

    if( maxNumModels != numModels )
    if( pModels )
    {
        maxNumModels = numModels;
        // Calculate the total number of meshes
        for( unsigned long i=0; i < numModels; ++i )
        {
            Omen::IModel* pModel = pModels[i];
            if( pModel )
            {
                //pModel->updateBoundingVolume();
                numMeshes += pModel->meshCount();
            }
        }

        // Create vertex and index buffers and wireframe rasterizer for octree rendering
        //createOctreeBuffers(pModels[0]->scene());

        // If total amount of meshes has changed since last render-call,
        // update the mesh-list
        if( m_maxNumMeshes != numMeshes )
        {
            if( m_pListMeshes )
                delete[] m_pListMeshes;
            m_pListMeshes = new Omen::IMesh*[numMeshes];

            m_maxNumMeshes = numMeshes;

            unsigned long meshIndex = 0;
            for( unsigned long i=0; i < numModels; ++i )
            {
                Omen::IModel* pModel = pModels[i];
                if( pModel )
                {
                    //Make also sure that meshes will get the shader parameter
                    std::wstring strShader;
                    std::wstring strTexture;
                    // Create first the shader
                    pModel->getProperty( L"shader", strShader );
                    pModel->getProperty( L"texture", strTexture );
                    
                    unsigned long meshCount = pModel->meshCount();
                    pModel->getMeshes( &m_pListMeshes[meshIndex],  meshCount );
                    for( unsigned long iMesh = 0; iMesh < meshCount; ++iMesh )
                    {
                        IMesh* pMesh = m_pListMeshes[meshIndex+iMesh];
                        if( !pMesh || !pMesh->vertexCount() )
                            continue;

                        std::wstring meshTexture;
                        
                        if( pMesh->getProperty( L"texture", meshTexture ) )
                            strTexture = meshTexture;

                        if( !pMesh->texture() && !strTexture.empty() )
                        {
                            std::vector<Omen::IMesh::Face>::iterator face;
                            pMesh->getFace(0, face);
                            strTexture = face->pMaterial->textureFilename();
                            if( strTexture.empty() )
                                break;
                           
                            // Now as we've got the factory, get the kernel pointer
                            Omen::IKernel& pKernel = GetOmenFactory().getKernel();

                            std::wstring texturePath;
        
                            // Get the texture file path;
                            IAssetManager* pAssetManager = pKernel.getAssetManager();
                            if( pAssetManager )
                            {
                                std::vector<Omen::IAssetNode*> assets;
                                if( pAssetManager->findAssets( Omen::Asset_TextureMap, strTexture, assets ) )
                                {
                                    if( !assets.empty() )
                                    {
                                        IAsset* pTextureAsset = assets[0]->asset();
                                        if( pTextureAsset )
                                            texturePath = pTextureAsset->path()+pTextureAsset->filename();
                                    }
                                }
                                else
                                {
                                    strTexture = L"";
                                }

                            }
                            
                            if( !strTexture.empty() )
                            {
                                std::wcout << L"Trying to find texturemap: " << strTexture << std::endl;
                                // Get the data directory
                                std::wstring data_dir = pKernel.getProperty( L"data-dir" );
                        
                                TexturesMap::iterator textureIter = m_textures.find(strTexture);
                                if(  textureIter != m_textures.end() )
                                {
                                    pMesh->setTexture(textureIter->second);
                                }
                                else
                                {
                                    if( texturePath.empty() )
                                        texturePath = data_dir+L"/"+strTexture;

                                    Omen::IImageFileReader* pReader = pKernel.getStorageServer()->getImageFileReader(texturePath);
                                    if( pReader )
                                    {
                                        ITexture* pTexture = pReader->createTexture(texturePath);
                                        if( pTexture )
                                        {
                                            pMesh->setTexture(pTexture);
                                            m_textures[strTexture] = pTexture;
                                        }
                                    }
                                }
                            }
                        }
                        if( pMesh->texture() )
                        {
                            ITexture* pTexture = pMesh->texture();
                            DirectX_10_Texture* pDxTexture = dynamic_cast<DirectX_10_Texture*>(pTexture);
                            if( pDxTexture )
                            {
                                pDxTexture->Initialize(m_device);
                            }
                        }
                        std::wstring meshShader;
                        if( !pMesh->getProperty( L"shader",meshShader ) && !strShader.empty() )
                            pMesh->setProperty( L"shader", strShader );
                        
                        std::wstring scaleProperty;
                        if( !pMesh->getProperty( L"scale",scaleProperty ) && pModel->getProperty(L"scale",scaleProperty ) )
                        {
                            pModel->getProperty(L"scale",scaleProperty );
                            std::wstringstream ss(scaleProperty);
                            Omen::Float scaleX,scaleY,scaleZ;
                            ss >> scaleX >> scaleY >> scaleZ;
                            //pMesh->setScale(scaleX,scaleY,scaleZ);
                        }
                    }
                    meshIndex += pModel->meshCount();
                }
            }
        
            for( unsigned long meshIndex = 0; meshIndex < m_maxNumMeshes; ++meshIndex )
            {
                if( m_pListMeshes[meshIndex] )
                {
                    // Get the index and vertex buffers
                    ID3D10Buffer* pVertexBuffer = reinterpret_cast<ID3D10Buffer*>(m_pListMeshes[meshIndex]->vertexBufferPtr());
                    ID3D10Buffer* pIndexBuffer = reinterpret_cast<ID3D10Buffer*>(m_pListMeshes[meshIndex]->indexBufferPtr());
                
                    // If they don't exist yet, create the buffers
                    if( !pVertexBuffer )
                    {
                        std::wstring strShader;
                        // Create first the shader
                        if( m_pListMeshes[meshIndex]->getProperty( L"shader", strShader ) )
                        {
                            Omen::IShader* pShader = NULL;
                            if( createShader( strShader, pShader ) )
                            {
                                const_cast<DirectX_10_Renderer*>(this)->m_shaders[strShader] = pShader;

                                m_pListMeshes[meshIndex]->setVertexShaderPtr(pShader);
                            }
                        }

                        // Then create the vertex buffer
                        createVertexBuffer(m_pListMeshes[meshIndex]);
                        pVertexBuffer = reinterpret_cast<ID3D10Buffer*>(m_pListMeshes[meshIndex]->vertexBufferPtr());
                    }
                    if( !pIndexBuffer )
                    {
                        createIndexBuffer(m_pListMeshes[meshIndex]);
                        pIndexBuffer = reinterpret_cast<ID3D10Buffer*>(m_pListMeshes[meshIndex]->indexBufferPtr());
                    }

                    // If we don't have the buffer even now, skip rendering this mesh
                    if( !pVertexBuffer )
                        continue;
                }
            }
        }
    }
}


///
/// setBuffers update the vertex and index buffers to the shader
///
void DirectX_10_Renderer::setBuffers( Omen::IMesh* pMesh ) const
{
    unsigned int stride;
    unsigned int offset;

    // Set vertex buffer stride and offset.
    stride = sizeof(DX_10_VertexType); 
    offset = 0;
    
    // Set the vertex buffer to active in the input assembler so it can be rendered.
    ID3D10Buffer* pVBuf = (ID3D10Buffer*)pMesh->vertexBufferPtr();
    ID3D10Buffer* pIBuf = (ID3D10Buffer*)pMesh->indexBufferPtr();

    m_device->IASetVertexBuffers(0, 1, &pVBuf, &stride, &offset);

    // Set primitive topology
    m_device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

    // Set the index buffer to active in the input assembler so it can be rendered.
    m_device->IASetIndexBuffer(pIBuf, DXGI_FORMAT_R32_UINT, 0);

    // Activate current rasterizer
    m_device->RSSetState(m_rasterState);
}

///
/// setBuffers update the vertex and index buffers to the shader
///
void DirectX_10_Renderer::setOctreeBuffers( const OctreeBuffer& octreebuf ) const
{
    unsigned int stride;
    unsigned int offset;

    // Set vertex buffer stride and offset.
    stride = sizeof(DX_10_VertexType); 
    offset = 0;
    
    // Set the vertex buffer to active in the input assembler so it can be rendered.
    ID3D10Buffer* pVBuf = (ID3D10Buffer*)octreebuf.m_pOctreeVertices;
    ID3D10Buffer* pIBuf = (ID3D10Buffer*)octreebuf.m_pOctreeIndices;

    m_device->IASetVertexBuffers(0, 1, &pVBuf, &stride, &offset);

    // Set primitive topology
    m_device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_LINELIST );

    // Set the index buffer to active in the input assembler so it can be rendered.
    m_device->IASetIndexBuffer(pIBuf, DXGI_FORMAT_R32_UINT, 0);

    // Activate current wireframe rasterizer
    m_device->RSSetState(rasterizer_wireframe);
}

///
/// setBuffers update the vertex and index buffers to the shader
///
void DirectX_10_Renderer::setBoundingBoxBuffers( const BoundingBoxBuffer& buffer ) const
{
    unsigned int stride;
    unsigned int offset;

    // Set vertex buffer stride and offset.
    stride = sizeof(DX_10_VertexType); 
    offset = 0;
    
    // Set the vertex buffer to active in the input assembler so it can be rendered.
    ID3D10Buffer* pVBuf = (ID3D10Buffer*)buffer.m_pVertices;
    ID3D10Buffer* pIBuf = (ID3D10Buffer*)buffer.m_pIndices;

    m_device->IASetVertexBuffers(0, 1, &pVBuf, &stride, &offset);

    // Set primitive topology
    m_device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_LINELIST );

    // Set the index buffer to active in the input assembler so it can be rendered.
    m_device->IASetIndexBuffer(pIBuf, DXGI_FORMAT_R32_UINT, 0);

    // Activate current wireframe rasterizer
    m_device->RSSetState(rasterizer_wireframe);
}

///
/// render(IModel**,unsigned int) renders the given number of models from the list
///
void DirectX_10_Renderer::render(Omen::IModel** pModels, unsigned int numModels) const
{
    m_frameIndex++;
    const_cast<DirectX_10_Renderer*>(this)->refreshRenderer( pModels,numModels );

    // Material definition for the shader
    struct Material
    {
        D3DXVECTOR4 ambient, diffuse, specular;
        float shininess;
    };

    // Set the point light
    struct PointLight
    {
        D3DXVECTOR4 color;
        D3DXVECTOR3 position;
    };

    PointLight pointLight;
    
    pointLight.color = D3DXVECTOR4(1.0f,1.0,1.0f,1.0f);
    
    Omen::Vector3d lightPos( 3.0, 5.0, 3.0 );
    //lightPos += m_pCamera->forward()*5.0;
    pointLight.position = D3DXVECTOR3( lightPos.x, lightPos.y, lightPos.z );
    
    unsigned long facesDrawn = 0;
    /**
void Camera::SetViewByMouse(void) 
{
    // the coordinates of our mouse coordinates   
    int MouseX, MouseY;   

    // the middle of the screen in the x direction   
    int MiddleX = SCREENWIDTH/2;   
    
    // the middle of the screen in the y direction   
    int MiddleY = SCREENHEIGHT/2;   
    
    // vector that describes mouseposition - center   
    Vector MouseDirection(0, 0, 0);   
    
    // static variable to store the rotation about the x-axis, since   
    // we want to limit how far up or down we can look.   
    // We don't need to cap the rotation about the y-axis as we   
    // want to be able to turn around 360 degrees   
    static double CurrentRotationAboutX = 0.0;   
    
    // The maximum angle we can look up or down, in radians   
    double maxAngle = 1;   
    
    // This function gets the position of the mouse   
    SDL_GetMouseState(&MouseX, &MouseY);   
    
    // if the mouse hasn't moved, return without doing   
    
    // anything to our view   
    if((MouseX == MiddleX) && (MouseY == MiddleY)) 
        return;   
        
    // otherwise move the mouse back to the middle of the screen   
    SDL_WarpMouse(MiddleX, MiddleY);   
    
    // get the distance and direction the mouse moved in x (in   
    // pixels). We can't use the actual number of pixels in radians,   
    // as only six pixels  would cause a full 360 degree rotation.   
    // So we use a mousesensitivity variable that can be changed to   
    // vary how many radians we want to turn in the x-direction for   
    // a given mouse movement distance   
    // We have to remember that positive rotation is counter-clockwise.    
    // Moving the mouse down is a negative rotation about the x axis   
    // Moving the mouse right is a negative rotation about the y axis   
    MouseDirection.x = (MiddleX - MouseX)/MouseSensitivity;    
    MouseDirection.y = (MiddleY - MouseY)/MouseSensitivity;   
    CurrentRotationX += MouseDirection.y;      
    
    // We don't want to rotate up more than one radian, so we cap it.   
    if(CurrentRotationX > 1)   
    {
        CurrentRotationX = 1; return;   
    }   
    
    // We don't want to rotate down more than one radian, so we cap it.   
    if(CurrentRotationX < -1)   
    { 
        CurrentRotationX = -1; return;   
    }   
    else
    {
        // get the axis to rotate around the x-axis.
        Vector Axis = CrossProduct(View - Position, Up);
        
        // To be able to use the quaternion conjugate, the axis to
        // rotate around must be normalized.
        Axis = Normalize(Axis);

        // Rotate around the x axis
        RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
        
        // Rotate around the y axis
        RotateCamera(MouseDirection.x, 0, 1, 0);
     }
}

/// This function actually rotates our view. After we are done, 
/// just plug your camera vectors (Position, View, and Up) into 
/// gluLookAt(Position.x, Position.y, Position.z, View.x, View.y, View.z, Up.x, Up.y, Up.z). 
/// Here is the code for the rotation.
void RotateCamera(double Angle, double x, double y, double z) 
{ 
    quaternion temp, quat_view, result;
    temp.x = x * sin(Angle/2);
    temp.y = y * sin(Angle/2);
    temp.z = z * sin(Angle/2);
    temp.w = cos(Angle/2);
    quat_view.x = View.x;
    quat_view.y = View.y;
    quat_view.z = View.z;
    quat_view.w = 0;
    
    result = mult(mult(temp, quat_view), conjugate(temp));   

    View.x = result.x;
    View.y = result.y;
    View.z = result.z;
}  

Again, at the end of the above functions, you should call
gluLookAt(Position.x, Position.y, Position.z,
          View.x, View.y, View.z, 
          Up.x, Up.y, Up.z).
/// and your camera should work just perfectly. Maybe some other time, 
/// I'll do a third person camera tutorial, and explain how to use SLERP.
    **/

    for( unsigned long iMesh = 0; iMesh < this->m_maxNumMeshes; ++iMesh )
    if( m_pListMeshes && m_pListMeshes[iMesh] )
    {
        // Render a triangle
        D3D10_TECHNIQUE_DESC techDesc;
        Omen::IMesh* pMesh = m_pListMeshes[iMesh];
        if( pMesh )
        {
            Omen::IShader* pIShader = pMesh->vertexShaderPtr();
            Omen::BasicShader* pShader = dynamic_cast<BasicShader*>(pIShader);
            if( pShader && pShader->isValid() )
            {
                // Update the vertex and index buffers 
                setBuffers(pMesh);
                
                // Set the projection matrix
                Omen::Matrix4x4 projMatrix;
                m_pCamera->getProjectionMatrix(projMatrix);
                (pShader->projectionMatrix())->SetMatrix( ( float* )projMatrix.float_data());

                // Set the view matrix
                Omen::Matrix4x4 rotationMatrix;
                Omen::Matrix4x4 viewMatrix;
                Omen::Matrix4x4 trans;
                Omen::Matrix4x4 rot;
                
                m_pCamera->transform().lookAt(m_pCamera->position()+Vector3d(0.0,0.0,1.0));
                
                rotationMatrix.setYawPitchRoll( m_pCamera->yaw(), m_pCamera->pitch(), m_pCamera->roll());
                Vector3d eye, lookAt, up;
                eye = m_pCamera->position();
                lookAt = Vector3d( 0.0, 0.0, 1.0 );
                lookAt = rotationMatrix * lookAt;
                lookAt = eye + lookAt;
                up = Vector3d( 0.0, 1.0, 0.0 );
                viewMatrix.lookAt( eye, lookAt, up );
                m_pCamera->getViewMatrix(viewMatrix);
                (pShader->viewMatrix())->SetMatrix( (float*)viewMatrix.float_data());
                
                // Initialize the world matrix
                Omen::Matrix4x4 worldMat;
                worldMat = pMesh->transformation();
                (pShader->worldMatrix())->SetMatrix( (float*)worldMat.float_data() );

                // Set the camera position to the shader
                (pShader->eyeVariable())->SetFloatVector( (float*)&eye.x );
   
                ID3D10EffectVariable* pVar = pShader->effect()->GetVariableByName( "cameraLight" );
                pVar->SetRawValue(&pointLight, 0, sizeof(pointLight));

                
                
                /// Set the texture
                ID3D10EffectVariable* pTextureValidator = pShader->effect()->GetVariableByName( "shaderTextureValid" );
                int bShaderTextureValid = FALSE;
                ITexture* pTexture = pMesh->texture();
                DirectX_10_Texture* pDxTexture = dynamic_cast<DirectX_10_Texture*>(pTexture);
                if( pDxTexture )
                {
                    if( !pDxTexture->GetTexture() )
                        pDxTexture->Initialize(m_device);
                    (pShader->textureVariable())->SetResource( pDxTexture->GetTexture() );
                    bShaderTextureValid = TRUE;
                }
                else
                    (pShader->textureVariable())->SetResource( NULL );

                pTextureValidator->SetRawValue( (void*)&bShaderTextureValid, 0, 1 );

                // Set the material parameters
                Omen::IMaterial* pMaterial = pMesh->material(0);
                Material material;
                if( pMaterial )
                {
                    memcpy( material.ambient, &pMaterial->ambientColor(), sizeof( D3DXVECTOR4 ) );
                    memcpy( material.diffuse, &pMaterial->diffuseColor(), sizeof( D3DXVECTOR4 ) );
                    memcpy( material.specular, &pMaterial->specularColor(), sizeof( D3DXVECTOR4 ) );
                    material.shininess = material.shininess;
                }
                else
                {
                    material.ambient =  D3DXVECTOR4(0.2f, 0.2f, 0.2f, 1.0f);
                    material.diffuse =  D3DXVECTOR4(0.8f, 0.8f, 0.8f, 1.0f);
                    material.specular = D3DXVECTOR4(0.5f, 0.5f, 0.5f, 1.0f);
                    material.shininess = 50.0f;
                }
                pVar = pShader->effect()->GetVariableByName( "Material" );
                pVar->SetRawValue(&material, 0, sizeof(Material));

                /// Draw the mesh 
                pShader->technique()->GetDesc( &techDesc );
                for( UINT p = 0; p < techDesc.Passes; ++p )
                {
                    pShader->technique()->GetPassByIndex( p )->Apply( 0 );
                    m_device->DrawIndexed( pMesh->faceCount()*3,0,0 );
                    facesDrawn += pMesh->faceCount();
                }
            }
        }
    }

    //////////////////////////////////////////////////////////////////////////////////
    if( m_bOctreeVisible )
    {
        Omen::IShader* pIShader = m_pListMeshes[0]->vertexShaderPtr();
        Omen::BasicShader* pShader = dynamic_cast<BasicShader*>(pIShader);
        if( pShader )
        {
            // Disable depth testing
            m_device->OMSetDepthStencilState(m_depthStencilState, 0);
            unsigned int depth = GetOmenFactory().getKernel().getProperty( L"octree_depth" );
            for( unsigned int iOctree = 0; iOctree < m_listOctreeBuffers.size(); ++iOctree )
            {
                if( depth < m_listOctreeBuffers.at(iOctree).m_depth )
                    continue;

                // Update the vertex and index buffers 
                setOctreeBuffers(m_listOctreeBuffers.at(iOctree));
                
                // Set the projection matrix
                Omen::Matrix4x4 projMatrix;
                m_pCamera->getProjectionMatrix(projMatrix);
                (pShader->projectionMatrix())->SetMatrix( ( float* )projMatrix.float_data());

                // Set the view matrix
                Omen::Matrix4x4 rotationMatrix;
                Omen::Matrix4x4 viewMatrix;
                Omen::Matrix4x4 trans;
                Omen::Matrix4x4 rot;
                rotationMatrix.setYawPitchRoll( m_pCamera->yaw() * Omen::PI_OVER_180, m_pCamera->pitch() * Omen::PI_OVER_180, m_pCamera->roll() * Omen::PI_OVER_180 );
                Vector3d eye, lookAt, up;
                eye = m_pCamera->position();
                lookAt = Vector3d( 0.0, 0.0, 1.0 );
                lookAt = rotationMatrix * lookAt;
                lookAt = eye + lookAt;
                up = Vector3d( 0.0, 1.0, 0.0 );
                viewMatrix.lookAt( eye, lookAt, up );
                (pShader->viewMatrix())->SetMatrix( (float*)viewMatrix.float_data());
                
                // Initialize the world matrix
                Omen::Matrix4x4 worldMat;
                //worldMat = pMesh->transformation();
                (pShader->worldMatrix())->SetMatrix( (float*)worldMat.float_data() );

                // Set the camera position to the shader
                (pShader->eyeVariable())->SetFloatVector( (float*)&eye.x );
   
                ID3D10EffectVariable* pVar = pShader->effect()->GetVariableByName( "cameraLight" );
                pVar->SetRawValue(&pointLight, 0, sizeof(pointLight));

                /// Set the texture
                ID3D10EffectVariable* pTextureValidator = pShader->effect()->GetVariableByName( "shaderTextureValid" );
                (pShader->textureVariable())->SetResource( NULL );
                bool bShaderTextureValid = false;
                pTextureValidator->SetRawValue( (void*)&bShaderTextureValid, 0, 1 );

                // Set the material parameters
                Material material;
                material.ambient =  D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
                material.diffuse =  D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
                material.specular = D3DXVECTOR4(0.5f, 0.5f, 0.5f, 1.0f);
                material.shininess = 50.0f;

                pVar = pShader->effect()->GetVariableByName( "Material" );
                pVar->SetRawValue(&material, 0, sizeof(Material));

                /// Draw the mesh 
                D3D10_TECHNIQUE_DESC techDesc;
                pShader->technique()->GetDesc( &techDesc );
                for( UINT p = 0; p < techDesc.Passes; ++p )
                {
                    pShader->technique()->GetPassByIndex( p )->Apply( 0 );
                    m_device->DrawIndexed( m_listOctreeBuffers.at(iOctree).m_octreeIndices,0,0 );
                }
            }
        }
    }
    //////////////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////////
    // Draw bounding boxes
    if( m_bBoundingVolumesVisible )
    {
        Omen::IShader* pIShader = m_pListMeshes[1]->vertexShaderPtr();
        Omen::BasicShader* pShader = dynamic_cast<BasicShader*>(pIShader);
        if( pShader )
        {
            // Disable depth testing
            m_device->OMSetDepthStencilState(m_depthStencilState, 0);
            for( unsigned int iBoundingBox = 0; iBoundingBox < m_listBoundingBoxBuffers.size(); ++iBoundingBox )
            {
                // Update the vertex and index buffers 
                setBoundingBoxBuffers(m_listBoundingBoxBuffers.at(iBoundingBox));
                
                // Set the projection matrix
                Omen::Matrix4x4 projMatrix;
                m_pCamera->getProjectionMatrix(projMatrix);
                (pShader->projectionMatrix())->SetMatrix( ( float* )projMatrix.float_data());

                // Set the view matrix
                Omen::Matrix4x4 rotationMatrix;
                Omen::Matrix4x4 viewMatrix;
                Omen::Matrix4x4 trans;
                Omen::Matrix4x4 rot;
                rotationMatrix.setYawPitchRoll( m_pCamera->yaw() * Omen::PI_OVER_180, m_pCamera->pitch() * Omen::PI_OVER_180, m_pCamera->roll() * Omen::PI_OVER_180 );
                Vector3d eye, lookAt, up;
                eye = m_pCamera->position();
                lookAt = Vector3d( 0.0, 0.0, 1.0 );
                lookAt = rotationMatrix * lookAt;
                lookAt = eye + lookAt;
                up = Vector3d( 0.0, 1.0, 0.0 );
                viewMatrix.lookAt( eye, lookAt, up );
                (pShader->viewMatrix())->SetMatrix( (float*)viewMatrix.float_data());
                
                // Initialize the world matrix
                Omen::Matrix4x4 worldMat;
                //worldMat = pMesh->transformation();
                (pShader->worldMatrix())->SetMatrix( (float*)worldMat.float_data() );

                // Set the camera position to the shader
                (pShader->eyeVariable())->SetFloatVector( (float*)&eye.x );
   
                ID3D10EffectVariable* pVar = pShader->effect()->GetVariableByName( "cameraLight" );
                pVar->SetRawValue(&pointLight, 0, sizeof(pointLight));

                /// Set the texture
                ID3D10EffectVariable* pTextureValidator = pShader->effect()->GetVariableByName( "shaderTextureValid" );
                (pShader->textureVariable())->SetResource( NULL );
                bool bShaderTextureValid = false;
                pTextureValidator->SetRawValue( (void*)&bShaderTextureValid, 0, 1 );

                // Set the material parameters
                Material material;
                material.ambient =  D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
                material.diffuse =  D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
                material.specular = D3DXVECTOR4(0.5f, 0.5f, 0.5f, 1.0f);
                material.shininess = 50.0f;

                pVar = pShader->effect()->GetVariableByName( "Material" );
                pVar->SetRawValue(&material, 0, sizeof(Material));

                /// Draw the mesh 
                D3D10_TECHNIQUE_DESC techDesc;
                pShader->technique()->GetDesc( &techDesc );
                for( UINT p = 0; p < techDesc.Passes; ++p )
                {
                    pShader->technique()->GetPassByIndex( p )->Apply( 0 );
                    m_device->DrawIndexed( m_listBoundingBoxBuffers.at(iBoundingBox).m_numIndices,0,0 );
                }
            }
        }
    }
    //////////////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////////
    // Create a rectangle to indicate where on the screen it should be drawn
    m_device->RSSetState(m_rasterState);
    m_textSprite->Begin(D3DX10_SPRITE_SAVE_STATE);
    RECT rct;
    rct.left=2;
    rct.right=780;
    rct.top=10;
    rct.bottom=rct.top+100;

    // Create a colour for the text - in this case blue
    D3DXCOLOR fontColor = D3DXCOLOR(255,255,0,255);   

    Matrix4x4 mat;
    m_pCamera->getViewMatrix(mat);
    // Set the view matrix
    Omen::Matrix4x4 rotationMatrix;
    Omen::Matrix4x4 viewMatrix;
    Omen::Matrix4x4 trans;
    Omen::Matrix4x4 rot;
    rotationMatrix.setYawPitchRoll( m_pCamera->yaw(),0.0,0.0);// m_pCamera->pitch(), m_pCamera->roll() );
    Vector3d eye, lookAt, up;
    eye = m_pCamera->position();
    lookAt = Vector3d( 0.0, 0.0, 1.0 );
    lookAt = rotationMatrix * lookAt;
    lookAt = eye + lookAt;
    up = Vector3d( 0.0, 1.0, 0.0 );
    viewMatrix.lookAt( eye, lookAt, up );
    std::wstring strMatrix;
    rotationMatrix.translate( 0, 0, 5.0 );
    printMatrix( rotationMatrix, strMatrix );
    // Draw some text
    strMatrix.insert(0,L"LookAt Matrix[Omen Matrix]\n" );
    std::wstring cameraName;
    m_pCamera->getProperty( L"name", cameraName );
    cameraName.append( L"\n\n" );
    strMatrix.insert(0,cameraName);
    strMatrix.insert(0,L"Camera:" );
    m_font->DrawText(m_textSprite, strMatrix.c_str(), -1, &rct, 0, fontColor );

    rct.top = rct.bottom+10;
    rct.bottom = rct.top+250;

    // Draw some text
    printMatrix( mat, strMatrix );
    strMatrix.insert(0,L"Quaternion->Matrix[Omen Matrix]\n" );
    m_font->DrawText(m_textSprite, strMatrix.c_str(), -1, &rct, 0, fontColor );

    std::wstring strFacesDrawn;
    std::wstringstream wss(strFacesDrawn);

    /*Omen::Float t2 = GetOmenFactory().getKernel().timer()->totalTime();
    wss << L"Faces drawn: " << facesDrawn << ", for frame index: " << m_frameIndex << ", time taken to draw: " << t2-t1;
    strFacesDrawn = wss.str();
    m_font->DrawText( m_textSprite, strFacesDrawn.c_str(), -1, &rct, 0, fontColor );
    
    // Draw FPS rate
    Omen::Float cur_time = GetOmenFactory().getKernel().timer()->totalTime();
    rct.top = rct.bottom+10;
    rct.bottom = rct.top+100;
    std::wstring strFPS;
    wss = std::wstringstream(strFPS);

    wss << L"FPS: " << 1.0/(cur_time-fps_time);
    strFPS = wss.str();
    m_font->DrawText( m_textSprite, strFPS.c_str(), -1, &rct, 0, fontColor );*/


    m_textSprite->End();
    //////////////////////////////////////////////////////////////////////////////////
}

//=============================================================================
/**
**  <summary>Rendering function</summary>
**
*/
/*
void DirectX_10_Renderer::render(Omen::IKernel* pKernel)
{
    // Clear the buffers to begin the scene.
    BeginScene(0,0,0, 1.0f);

    D3DXMATRIX worldMatrix, viewMatrix, projectionMatrix;

    worldMatrix = m_worldMatrix;
    projectionMatrix = m_projectionMatrix;

    // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
    m_pModel->Render(m_device);

    // Render the model using the color shader.
    m_pLightShader->Render( m_device, 
                            m_pModel->GetIndexCount(), 
                            worldMatrix, 
                            viewMatrix, 
                            projectionMatrix, 
                            m_pModel->GetTexture(), 
                            m_pLight->GetDirection(), 
                            m_pLight->GetDiffuseColor());

    
    

    float camZ = 0.0;
    pKernel.getProperty(L"camera_z", camZ );
    camZ *= (float)0.2;
    pKernel.setProperty(L"camera_z", camZ );
}*/

 /// <summary>Create a shader with given name</summary>
bool DirectX_10_Renderer::createShader( const std::wstring& shaderName, Omen::IShader*& pShader ) const
{
    bool bSuccess = false;

    ShadersMap::iterator shaderIter = m_shaders.find(shaderName);

    if( shaderIter != m_shaders.end() )
    {
        pShader = shaderIter->second;
    }
    else
    if( shaderName == L"diffuse-color" )
    {
        std::wstring data_dir = GetOmenFactory().getKernel().getProperty( L"data-dir" );

        BasicShader* pBasicShader = new BasicShader( m_device, data_dir+L"/shaders/diffuse_color.fx", L"", L"" );
        pShader = pBasicShader;
        m_shaders[shaderName] = pShader;
        
    }
    else
    {
        std::wstring data_dir = GetOmenFactory().getKernel().getProperty( L"data-dir" );

        BasicShader* pBasicShader = new BasicShader( m_device, data_dir+L"/shaders/"+shaderName, L"", L"" );
        pShader = pBasicShader;
        m_shaders[shaderName] = pShader;
    }

    if( pShader && pShader->isValid() )
        bSuccess = true;

    return bSuccess;
}